<?php

namespace App\Utils;

use App\Constants\ChannelTypeEnum;
use App\Constants\Constants;
use App\Constants\OppoAscribeTypeEnum;
use App\Constants\OppoEventTypeEnum;
use App\Model\Report\ReportThirdLog;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Guzzle\ClientFactory;

class OppoUtil
{
    #[Inject]
    protected ClientFactory $clientFactory;

    public static function getReportTimeColumnByEventType($eventType): string
    {
        $map = [
            OppoEventTypeEnum::ACTIVATION->value => 'activation_time',
            OppoEventTypeEnum::NEXT_DAY->value   => 'next_day_time',
            OppoEventTypeEnum::GAME_KEY->value   => 'game_key_time',
            OppoEventTypeEnum::REGISTER->value   => 'register_time',
            OppoEventTypeEnum::PAY->value        => 'pay_time',
        ];

        return $map[$eventType] ?? "";
    }

    public static function getReportStatusColumnByEventType($eventType): string
    {
        $map = [
            OppoEventTypeEnum::ACTIVATION->value => 'activation_status',
            OppoEventTypeEnum::NEXT_DAY->value   => 'next_day_status',
            OppoEventTypeEnum::GAME_KEY->value   => 'game_key_status',
            OppoEventTypeEnum::REGISTER->value   => 'register_status',
            OppoEventTypeEnum::PAY->value        => 'pay_status',
        ];

        return $map[$eventType] ?? "";
    }

    /**
     * 获取单个广告创意详情
     * https://adsfs.heytapimage.com/mp/static/omniapi/latest/index.html#5.2-%E8%8E%B7%E5%8F%96%E5%8D%95%E4%B8%AA%E5%B9%BF%E5%91%8A%E5%88%9B%E6%84%8F%E8%AF%A6%E6%83%85
     * @param $ownerId
     * @param $apiId
     * @param $apiKey
     * @param $adId
     * @return mixed
     * @throws GuzzleException
     */
    public function getAdDetail($ownerId, $apiId, $apiKey, $adId): mixed
    {
        $client = $this->clientFactory->create([
            'base_uri' => 'http://sapi.ads.heytapmobi.com/',
            'headers'  => [
                'Authorization' => $this->oppoAuthenticate($ownerId, $apiId, $apiKey),
            ]
        ]);

        $ret    = $client->get('v3/ad/get?adId=' . $adId)->getBody()->getContents();
        $retArr = json_decode($ret, true);

        return $retArr['data'] ?? $retArr;
    }

    /**
     * @throws GuzzleException
     */
    public function reportEvent($ascribeChannel, $version, $oaid, $eventType, $packageName, $device, $ascribeType,
                                $cpmComplete = 0): void
    {
        // 不是生产环境，则忽略
        // if (!is_prod()) {
        //     return;
        // }

        $timestamp = ProjectUtil::getMillisecondTime();

        // ouid 就是 oaid
        $ouId = AESUtil::ecbEncrypt($oaid, base64_decode(Constants::OPPO['base64Key']));

        $postData = [
            "ouId"        => $ouId,
            "timestamp"   => $timestamp,
            "pkg"         => $packageName, // 包名，如com.xxx; 如果是快应用，要填快应用id
            "dataType"    => (int)$eventType, // 激活类型,1激活，2注册
            "channel"     => 1, // 渠道，1OPPO，2一加，3其他
            "type"        => 0,   // Imei 原始加密类型1： md5 加密 0： 无加密（默认为0）如果传 oaid，type 值填 0
            "appType"     => 1, // 应用类别：1 应用 2 游戏 3 快应用 0 其他，默认 1 应用
            "ascribeType" => $ascribeType // 归因类型：1：广告主归因，0：OPPO归因（默认或者不填即为 0），2：助攻归因
        ];

        // 如果是付费
        if ($eventType == OppoEventTypeEnum::PAY->value) {
            // 这时传过来的cpmComplete是付费金额*10万，这里计算真实支付金额除10万，oppo传的是分，在乘100
            $payAmount = round($cpmComplete / 100000 * 100, 2);
            if ($payAmount > 0) {
                $postData['payAmount'] = $payAmount;
            }
        }

        // 如果是广告主归因, 则加上 adId 参数
        if ($ascribeType == OppoAscribeTypeEnum::OWNER->value) {
            $postData['adId'] = $device->ad_id;
        }

        $headerData = [
            'signature'    => md5(json_encode($postData) . $timestamp . Constants::OPPO['salt']),
            "timestamp"    => $timestamp,
            "Content-Type" => "application/json;charset=UTF-8"
        ];

        $ret = $this->clientFactory->create([
            'base_uri' => 'https://api.ads.heytapmobi.com/',
            'headers'  => $headerData
        ])->post('api/uploadActiveData', [
            'json' => $postData
        ])->getBody()->getContents();

        $retAry = json_decode($ret, true);

        ReportThirdLog::insertData($device->project_id, $device->app_id, ChannelTypeEnum::OPPO->value,
            $ascribeChannel, $version, $device->ad_id, $device->ad_plan_id, $oaid, $eventType, '', $postData,
            $retAry['ret'] ?? '', $retAry);
    }

    /**
     * 生成token用于ominiapi工程鉴权
     * @param $ownerId
     * @param $apiId
     * @param $apiKey
     * @return string
     */
    public function oppoAuthenticate($ownerId, $apiId, $apiKey): string
    {
        $time     = time();
        $signStr  = $apiId . $apiKey . $time;
        $sign     = sha1($signStr);
        $tokenStr = "$ownerId,$apiId,$time,$sign";
        $token    = base64_encode($tokenStr);
        return "Bearer $token";
    }
}